package com.onpositive.units;

import java.io.Serializable;
import java.util.Collection;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.onpositive.knowledge.model.values.IHasValue;
import com.onpositive.semantic.model.api.meta.BaseMeta;
import com.onpositive.semantic.model.api.meta.IHasMeta;
import com.onpositive.semantic.model.api.meta.IMeta;
import com.onpositive.semantic.model.api.meta.IWritableMeta;
import com.onpositive.semantic.model.api.property.IProperty;
import com.onpositive.semantic.model.api.property.IPropertyProvider;

public abstract class ParsedValue implements IHasValue, Serializable, IHasMeta{
	
	public static final String META_KEY_ID = "id";
	public static final String META_KEY_VALUE_TYPE = "value-type";


	/**
	 * 
	 */	
	
	private byte validity = Byte.MAX_VALUE ;
	
	public ParsedValue( String comment ){
		this.commentString = comment ;
	}
	
	public ParsedValue( Element element ){
		String comment = element.getAttribute("comment") ;
		this.commentString = comment ;
	}
	
	private static final long serialVersionUID = -3874725424265637944L;
	
	private final String commentString ;

	
	abstract public Object value();
	abstract public void setValue( Object obj );
	
	abstract public Object describer();
	abstract public String getId();
	abstract public String getValueAsString();
	
	public void writeValue(Element element )
	{		
		writeValuePartial(element);		
		element.setAttribute("value", getValueAsString() );
		
	}

	protected void writeValuePartial(Element element) {
		element.setAttribute( META_KEY_VALUE_TYPE, getMeta().getSingleValue( META_KEY_VALUE_TYPE, String.class, null ) );
		element.setAttribute( META_KEY_ID, getMeta().getSingleValue( META_KEY_ID, String.class, null ) );
		element.setAttribute("comment", getComment() );
	}
	
	@Override
	public abstract boolean equals(Object obj) ;
	
	@Override
	public abstract int hashCode();
	
	@Override
	public String toString()
	{
		return this.getValueAsString() ;
	}
	
	public String getContextFragmentString()
	{
		return this.getValueAsString() ;
	}
	
	public String getContentString()
	{
		return this.getValueAsString() ;
	}
	
	public String getComment(){
		return commentString ;
	}
	
	private IWritableMeta meta ;
	
	protected IWritableMeta getMetaInternal(){
		return meta ;
	}
	
	public IMeta getMeta(){
		if( meta == null )
			meta = createMeta() ;
		
		return meta ;			
	}
	
	protected  IWritableMeta createMeta() {
		
		BaseMeta meta = new BaseMeta() ;		
		meta.putMeta( META_KEY_VALUE_TYPE, getId() ) ;
		meta.putMeta( META_KEY_ID, getId() ) ;
		return meta ;
	}

	public byte getValidity() {
		return validity;
	}

	public void setValidity(byte validity) {
		this.validity = validity;
	}
	
	public abstract<T> Collection<T> getValues(Class<T>vs);

}
